
package cz.czu.pef.DataModelling.tests.data.prepare;

import java.util.*;
import java.util.logging.*;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.transaction.annotation.Transactional;

import cz.czu.pef.DataModelling.*;
import cz.czu.pef.DataModelling.domainObjects.*;
import cz.czu.pef.DataModelling.service.api.*;
import cz.czu.pef.DataModelling.tests.data.BasicData;
import cz.czu.pef.DataModelling.utils.Constants;

@Component(value = "prepareSharedData")
@SuppressWarnings("unused")
@ContextConfiguration(locations = {Constants.springTestingClasspathConfig})
public class PrepareSharedData extends BasicData
{

  Logger logger = Logger.getLogger(PrepareSharedData.class.getName());

  public long yearsToSeconds(long years)
  {
    return (long) ((double) years * 365.2422 * 24 * 60 * 60);
  }

  public void fillBasicData()
  {
    // ##############################################
    // TRAINING TYPES
    // ##############################################
    trainingTypeService.mergeUnique("code", Constants.TRAINING_TYPE_BOZP, new TrainingType(Constants.TRAINING_TYPE_BOZP, "Bezpečnost a ochrana zdraví při práci", "Školení - Bezpečnost a ochrana zdraví při práci", "Školení - BOZP", yearsToSeconds(1)));
    trainingTypeService.mergeUnique("code", Constants.TRAINING_TYPE_PO, new TrainingType(Constants.TRAINING_TYPE_PO, "Požární ochrana", "Školení - Požární ochrana", "Školení - PO", yearsToSeconds(1)));

    // ##############################################
    // MEDICAL EXAMINATION TYPES
    // ##############################################
    medicalExaminationTypeService.mergeUnique("code", Constants.MEDICAL_EXAMINATION_TYPE_PRAKTIK, new MedicalExaminationType(Constants.MEDICAL_EXAMINATION_TYPE_PRAKTIK, "Běžná prohlídka", "Prohlídka u obvodního lékaře"));
    medicalExaminationTypeService.mergeUnique("code", Constants.MEDICAL_EXAMINATION_TYPE_OCNI, new MedicalExaminationType(Constants.MEDICAL_EXAMINATION_TYPE_OCNI, "Oční vyšetření", "Vyšetření u očního lékaře"));
    medicalExaminationTypeService.mergeUnique("code", Constants.MEDICAL_EXAMINATION_TYPE_NEURO, new MedicalExaminationType(Constants.MEDICAL_EXAMINATION_TYPE_NEURO, "Neurologické vyšetření", "Vyšetření u neurologa"));
    medicalExaminationTypeService.mergeUnique("code", Constants.MEDICAL_EXAMINATION_TYPE_PSYCHO, new MedicalExaminationType(Constants.MEDICAL_EXAMINATION_TYPE_PSYCHO, "Psychologické vyšetření", "Vyšetření u psychologa"));
  }

  public void fillRandomTrainings()
  {
    TrainingType bozpTraningType = trainingTypeService.findByAttributeUniqueResult("code", Constants.TRAINING_TYPE_BOZP);
    if (bozpTraningType == null)
      throw new RuntimeException("bozpTraningType trainingType does not exists!");
    TrainingType poTraningType = trainingTypeService.findByAttributeUniqueResult("code", Constants.TRAINING_TYPE_PO);
    if (poTraningType == null)
      throw new RuntimeException("poTraningType trainingType does not exists!");

    MedicalExaminationType medExam_Praktik = medicalExaminationTypeService.findByAttributeUniqueResult("code", Constants.MEDICAL_EXAMINATION_TYPE_PRAKTIK);
    MedicalExaminationType medExam_Ocni = medicalExaminationTypeService.findByAttributeUniqueResult("code", Constants.MEDICAL_EXAMINATION_TYPE_OCNI);
    MedicalExaminationType medExam_Neurolog = medicalExaminationTypeService.findByAttributeUniqueResult("code", Constants.MEDICAL_EXAMINATION_TYPE_NEURO);
    MedicalExaminationType medExam_Psycholog = medicalExaminationTypeService.findByAttributeUniqueResult("code", Constants.MEDICAL_EXAMINATION_TYPE_PSYCHO);

    // add some training and medical examinations to persons
    List<Person> persons = personService.findAll();
    for (Person person : persons)
    {
      Calendar randomDates[] = new Calendar[10];
      for (int i = 0; i < 10; i++)
      {
        randomDates[i] = Calendar.getInstance();
        randomDates[i].add(Calendar.MONTH, -(new Random()).nextInt(48));
      }

      // add also some training
      person.addTraining(trainingService.merge(new Training(bozpTraningType, new Date(randomDates[0].getTime().getTime() + bozpTraningType.getDefaultPeriodInSeconds()*1000), randomDates[0].getTime())));
      person.addTraining(trainingService.merge(new Training(poTraningType, new Date(randomDates[1].getTime().getTime() + bozpTraningType.getDefaultPeriodInSeconds()*1000), randomDates[1].getTime())));

      if ((new Random()).nextInt() % 100 < 60)
      {
        person.addMedicalExamination(medicalExaminationService.merge(new MedicalExamination(medExam_Praktik, randomDates[2].getTime())));
      }
      if ((new Random()).nextInt() % 100 < 10)
        person.addMedicalExamination(medicalExaminationService.merge(new MedicalExamination(medExam_Ocni, randomDates[2].getTime())));
      if ((new Random()).nextInt() % 100 < 30)
        person.addMedicalExamination(medicalExaminationService.merge(new MedicalExamination(medExam_Neurolog, randomDates[2].getTime())));
      if ((new Random()).nextInt() % 100 < 20)
        person.addMedicalExamination(medicalExaminationService.merge(new MedicalExamination(medExam_Psycholog, randomDates[2].getTime())));

      person = personService.merge(person);
    }
  }

  public void fillRandomMachinery(Company company, MachineType[] genTypes)
  {
    for (int i = 0; i < 100; i++)
    {
      int randomType = (new Random()).nextInt(genTypes.length);
      String serialNo = company.getName() + "-SERIAL-NO-" + i;
      Machinery machTmp = machineryService.findByAttributeUniqueResult("machinerySerialNo", serialNo);
      if (machTmp == null)
      {
        logger.log(Level.FINE, "Creating new Machinery with serialNo = " + serialNo);
        machineryService.merge(machineryService.merge(new Machinery(serialNo, genTypes[randomType], null, company)));
      }
      else
      {
        System.out.println("Machinery with serialNo = " + serialNo + " already exists.");
      }
    }
  }
}
